#ifndef _ANTISYM_COEFF_
#define _ANTISYM_COEFF_
#include <cmath>
#include <eigen3/Eigen/Dense>
#include <eigen3/Eigen/SparseCore>
#include <vector>
#include <stdlib.h>
#include "../DF_Common/basis_state.h"
#include "../DF_Common/coupling_coeff.h"
#include "../DF_Common/progress_bar.h"
using std::cout;
using std::endl;
using std::vector;
using Eigen::MatrixXd;
using Eigen::SelfAdjointEigenSolver;

class Antisym{
 public:
  Antisym (SixJ_coeff &sixJ_t, NinJ_coeff &ninJ_t, Hobra &hobra_t, Jacobi &Jacobi_t):
  sixJ(sixJ_t),ninJ(ninJ_t),hobra_x(hobra_t),Jacobi_x(Jacobi_t){}

  const SixJ_coeff &sixJ;
  const NinJ_coeff &ninJ;
  const Hobra &hobra_x;
  Jacobi &Jacobi_x;

  MatrixXd anti_mat;

  vector<vector<vector<double>>> eig_val ; //eig_val[channel][E][i]
  vector<vector<vector<vector<double>>>> vec_D; //vec_D[channel][E][i][j]
  vector<vector<double>> eig_num; // eig_num[channel][E] double to check the completeness of Jacobi basis

  void cal();

  void cal(int channel,int E_min, int E_max){
    //cout<<"antiysym mat build begin"<<endl;
    this->JTmat_build(Jacobi_x,channel,E_min,E_max);
    //cout<<"antiysym mat build end"<<endl;
    this->mat_diag();
  }

  // private:
  double mat_cal(State_Jacobi &finial_state,State_Jacobi &init_state);
  void JTmat_build(Jacobi &Jacobi_t,int channel_num);
  void JTmat_build(Jacobi &Jacobi_t,int channel_num, int E);
  void JTmat_build(Jacobi &Jacobi_t,int channel_num, int E_min, int E_max);
  void print(std::string filename);
 private:

  int diag_flag=-1;
  int build_flag=-1;
  double anti_basis_num_d;
  vector<double> eig_val_t;
  int anti_basis_num;
  int cout_flag=-1;
  MatrixXd anti_vec_C;
  MatrixXd anti_vec_D;

  void mat_diag();

  void mark_Jaco(int channel,int E);
  int Tri(int &j2a,int &j2b,int &j2c);
  int Tri_state(State_Jacobi &state);
  int phase(int n);
};




#endif
